package com.scale.service.user.controller;

import com.example.common.result.Result;
import com.example.user.dto.ResetPasswordDTO;
import com.example.user.dto.UserLoginDTO;
import com.example.user.dto.UserRegisterDTO;
import com.example.user.vo.LoginResultVO;
import com.scale.service.user.service.UserAuthService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;

/**
 * 用户认证控制器
 * @author crp
 * @since 2025-09-23
 */
@Api(tags = "用户认证管理", description = "提供用户注册、登录、登出、密码重置等认证功能")
@Slf4j
@RestController
@RequestMapping("/api/auth")
@Validated
@CrossOrigin(origins = {
    "http://localhost:3000", 
    "http://127.0.0.1:3000", 
    "http://localhost:3001", 
    "http://127.0.0.1:3001", 
    "http://localhost:5173", 
    "http://127.0.0.1:5173"
}, maxAge = 3600, allowCredentials = "true")
public class UserAuthController {

    @Autowired
    private UserAuthService userAuthService;

    /**
     * 用户注册
     */
    @ApiOperation(value = "用户注册", notes = "新用户注册，支持邮箱或手机号验证")
    @PostMapping("/register")
    public Result<String> register(
            @ApiParam(value = "用户注册信息", required = true) 
            @Valid @RequestBody UserRegisterDTO registerDTO) {
        try {
            userAuthService.register(registerDTO);
            return Result.success("注册成功");
        } catch (Exception e) {
            log.error("用户注册失败: {}", e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * 用户登录
     */
    @ApiOperation(value = "用户登录", notes = "用户登录认证，支持用户名/邮箱/手机号登录")
    @PostMapping("/login")
    public Result<LoginResultVO> login(
            @ApiParam(value = "用户登录信息", required = true) 
            @Valid @RequestBody UserLoginDTO loginDTO) {
        try {
            LoginResultVO result = userAuthService.login(loginDTO);
            return Result.success("登录成功", result);
        } catch (Exception e) {
            log.error("用户登录失败: {}", e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * 用户登出
     */
    @ApiOperation(value = "用户登出", notes = "用户退出登录，清除令牌信息")
    @PostMapping("/logout")
    public Result<String> logout(HttpServletRequest request) {
        try {
            String token = extractToken(request);
            if (token != null) {
                userAuthService.logout(token);
            }
            return Result.success("登出成功");
        } catch (Exception e) {
            log.error("用户登出失败: {}", e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * 刷新令牌
     */
    @ApiOperation(value = "刷新访问令牌", notes = "使用刷新令牌获取新的访问令牌")
    @PostMapping("/refresh")
    public Result<LoginResultVO> refreshToken(
            @ApiParam(value = "刷新令牌", required = true) 
            @RequestParam @NotBlank(message = "刷新令牌不能为空") String refreshToken) {
        try {
            LoginResultVO result = userAuthService.refreshToken(refreshToken);
            return Result.success("令牌刷新成功", result);
        } catch (Exception e) {
            log.error("刷新令牌失败: {}", e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * 发送验证码
     */
    @ApiOperation(value = "发送验证码", notes = "向邮箱或手机号发送验证码，用于注册或密码重置")
    @PostMapping("/send-code")
    public Result<String> sendVerifyCode(
            @ApiParam(value = "接收验证码的账号（邮箱或手机号）", required = true) 
            @RequestParam @NotBlank(message = "账号不能为空") String account,
            @ApiParam(value = "验证类型：email-邮箱，phone-手机号", required = true, allowableValues = "email,phone") 
            @RequestParam @NotBlank(message = "验证类型不能为空") String type) {
        try {
            userAuthService.sendVerifyCode(account, type);
            return Result.success("验证码发送成功");
        } catch (Exception e) {
            log.error("发送验证码失败: {}", e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * 重置密码
     */
    @ApiOperation(value = "重置密码", notes = "通过验证码重置用户密码")
    @PostMapping("/reset-password")
    public Result<String> resetPassword(
            @ApiParam(value = "密码重置信息", required = true) 
            @Valid @RequestBody ResetPasswordDTO resetPasswordDTO) {
        try {
            userAuthService.resetPassword(resetPasswordDTO);
            return Result.success("密码重置成功");
        } catch (Exception e) {
            log.error("重置密码失败: {}", e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * 验证令牌
     */
    @ApiOperation(value = "验证访问令牌", notes = "验证当前访问令牌是否有效")
    @GetMapping("/validate")
    public Result<Boolean> validateToken(HttpServletRequest request) {
        try {
            String token = extractToken(request);
            if (token == null) {
                return Result.success("令牌验证结果", false);
            }
            boolean isValid = userAuthService.validateToken(token);
            return Result.success("令牌验证结果", isValid);
        } catch (Exception e) {
            log.error("验证令牌失败: {}", e.getMessage(), e);
            return Result.success("令牌验证结果", false);
        }
    }

    /**
     * 获取当前用户信息
     */
    @ApiOperation(value = "获取当前用户信息", notes = "根据访问令牌获取当前登录用户的基本信息")
    @GetMapping("/user-info")
    public Result<Long> getUserInfo(HttpServletRequest request) {
        try {
            String token = extractToken(request);
            if (token == null) {
                return Result.unauthorized("未提供访问令牌");
            }

            if (!userAuthService.validateToken(token)) {
                return Result.unauthorized("访问令牌无效");
            }

            Long userId = userAuthService.getUserIdFromToken(token);
            return Result.success("获取用户信息成功", userId);
        } catch (Exception e) {
            log.error("获取用户信息失败: {}", e.getMessage(), e);
            return Result.unauthorized("获取用户信息失败");
        }
    }

    /**
     * 从请求头中提取令牌
     */
    private String extractToken(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }
}
